﻿using System;
using System.Collections.Generic;
using System.Linq;
using Gumini.JulaDB.DataTypes;
using Gumini.JulaDB.Expressions.Functions;

namespace Gumini.JulaDB.Expressions
{
    internal class ScalarFunctionCall : Expression
    {
        private readonly ScalarFunction _function;

        public ScalarFunctionCall(ScalarFunction function, IList<Expression> children)
            : base(children.ToArray())
        {
            _function = function;
        }

        public IList<Expression> Children
        {
            get { return base._children; }
        }

        public override TypedValue Evaluate(List<Context<TypedValue>> context)
        {
            var childResults = Children.Select(c => c.Evaluate(context).Value);
            return new TypedValue(_function.GetReturnType(), _function.Evaluate(childResults.ToArray()));
        }

        public override DataType InferType(Context<DataType> context)
        {
            foreach(var c in Children)
                c.InferType(context);
            return _function.GetReturnType();
        }

        public override bool Equals(Expression other)
        {
            var b = other as ScalarFunctionCall;
            if (b == null)
                return false;
            return
                this._function.Equals(b._function) &&
                this.Children.SequenceEqual(b.Children);
        }

        public override string ToString()
        {
            return String.Format("{0}({1})", _function.Name, string.Join(", ", Children.ToString()));
        }
    }
}
